#ifndef ____SSBASEL__SSBASE__BASE_REFCOUNTED__H__
#define ____SSBASEL__SSBASE__BASE_REFCOUNTED__H__

#include "base.h"

_SSL_BEGIN
_SSBASEL_BEGIN

#ifdef _MSC_VER
#include "ssbase_win/base_win_export.h"
#endif

class SSBASE_CLASS ref_counted_interface
{
public:
	virtual ~ref_counted_interface() { }

public:
	virtual Atomic32 add_ref() const = 0;
	virtual Atomic32 release() const = 0;
	virtual bool has_one_ref() const = 0;
	virtual bool compare(ref_counted_interface *other) const = 0;
};

class SSBASE_CLASS ref_counted_base : virtual public ref_counted_interface
{
public:
	ref_counted_base();

public:
	virtual Atomic32 add_ref() const;
	virtual Atomic32 release() const;
	virtual bool has_one_ref() const;
	virtual bool compare(ref_counted_interface *other) const;

protected:
	mutable AtomicRefCount refcount_;
};
/*
template <class T, typename Traits>
class refcounted_thread_safe;

template<typename T>
struct refcounted_thread_safe_traits;

class SSBASE_CLASS refcounted_thread_safe_base
{
public:
	bool has_one_ref() const;

protected:
	refcounted_thread_safe_base();
	~refcounted_thread_safe_base();

	Atomic32 add_ref() const;
	Atomic32 release() const;

private:
	mutable AtomicRefCount refcount_;

	DISALLOW_CLASS_COPY_AND_ASSIGN(refcounted_thread_safe_base);
};

template<typename T>
struct default_refcounted_thread_safe_traits
{
	static void destruct(const T* x)
	{
		refcounted_thread_safe<T, default_refcounted_thread_safe_traits>::delete_internal(x);
	}
};

template <class T, typename Traits = default_refcounted_thread_safe_traits<T> >
class refcounted_thread_safe : public refcounted_thread_safe_base
{
public:
	refcounted_thread_safe() { }
	~refcounted_thread_safe() { }

	Atomic32 add_ref() const
	{
		return refcounted_thread_safe_base::add_ref();
	}

	Atomic32 release() const
	{
		Atomic32 ref_cnt = refcounted_thread_safe_base::release();
		if(ref_cnt == 0)
		{
			Traits::destruct(static_cast<const T*>(this));
		}
		return ref_cnt;
	}

private:
	friend struct default_refcounted_thread_safe_traits<T>;
	friend struct refcounted_thread_safe_traits<T>;
	static void delete_internal(const T* x) { delete x; }

	DISALLOW_CLASS_COPY_AND_ASSIGN(refcounted_thread_safe);
};
*/
_SSBASEL_END
_SSL_END

#endif
